package com.example.demo.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.async.AsyncService;
import com.example.demo.async.TestAsyncService;
import com.example.demo.entity.UserInfo;
import com.example.demo.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * @author LF
 * @date 2021/4/16 - 11:11
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户信息")
@Slf4j
public class UserInfoController {

    @Autowired
    UserInfoService userInfoService;

    @PostMapping("/add")
    @ApiOperation(value = "新增")
    public UserInfo save(@RequestParam(required = false)UserInfo userInfo){
        userInfoService.saveOrUpdate(userInfo);
        return userInfo;
    }

    @GetMapping("/list")
    @ApiOperation(value = "列表")
    public List<UserInfo> getUserInfoList(){
        List<UserInfo> userInfoList = userInfoService.list();
        return userInfoList;
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "根据ID查询")
    public UserInfo getUserInfo(@PathVariable("id") long id){
        UserInfo userInfo = userInfoService.getById(id);
        return userInfo;
    }

    @PutMapping("/update")
    @ApiOperation(value = "修改")
    public void Update(UserInfo userInfo){
        userInfoService.updateById(userInfo);
    }

    @DeleteMapping("/del/{id}")
    @ApiOperation(value = "根据ID删除")
    public void del(@PathVariable("id") long id){
        userInfoService.removeById(id);
    }

    @GetMapping("/page")
    public IPage<UserInfo> list() {
        /**
         * Page(current,size)
         * current:当前页,long类型
         * size:每页显示的数量,long类型
         * 可参考其构造方法
         */
        IPage<UserInfo> iPage = userInfoService.selectPage(new Page<>(1L,10));
        return iPage;
    }

    /**
     *利用监听器缓存数据   Application是缓存在内存中，对内存消耗大但前端响应快
     * @param request
     * @return
     */
    @GetMapping("/listenerUser")
    public UserInfo getUser(HttpServletRequest request) {
        ServletContext application = request.getServletContext();
        return (UserInfo) application.getAttribute("user-info");
    }

    /**
     * 获取当前在线人数，该方法有bug
     *
     * 请求相同的地址可以看到 count 是 2，这没有问题。但是如果关闭一个浏览器再打开，理论上应该还是 2，但是实际测试却是 3。原因是 Session
     * 销毁的方法没有执行（可以在后台控制台观察日志打印情况），当重新打开时，服务器找不到用户原来的 Session，于是又重新创建了一个 Session
     * @param request
     * @return
     */
    @GetMapping("/listenerTotal")
    public String getTotalUser(HttpServletRequest request) {
        Integer count = (Integer) request.getSession().getServletContext().getAttribute("count");
        return "当前在线人数：" + count;
    }

    /**
     * 获取当前在线人数
     *
     * 该处理逻辑是让服务器记得原来那个 Session，即把原来的 sessionId 记录在浏览器中，下次再打开时，把这个 sessionId 传过去，
     * 这样服务器就不会重新再创建了。重启一下服务器，在浏览器中再次测试一下，即可避免上面的问题
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/listenerTotal2")
    public String getTotalUser2(HttpServletRequest request, HttpServletResponse response) {
        Cookie cookie;
        try {
            // 把 sessionId 记录在浏览器中
            cookie = new Cookie("JSESSIONID", URLEncoder.encode(request.getSession().getId(), "utf-8"));
            cookie.setPath("/");
            //设置 cookie 有效期为 2 天，设置长一点
            cookie.setMaxAge( 48*60 * 60);
            response.addCookie(cookie);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Integer count = (Integer) request.getSession().getServletContext().getAttribute("count");
        return "当前在线人数：" + count;
    }

    @GetMapping("/listenerRequest")
    public String getRequestInfo(HttpServletRequest request) {
        log.info("requestListener中的初始化的name数据：" + request.getAttribute("name"));
        return request.getAttribute("name").toString();
    }

    @GetMapping("/listenerUser2")
    public UserInfo listenerUser(HttpServletRequest request){
        ServletContext application = request.getServletContext();
        UserInfo user = (UserInfo)application.getAttribute("user-info2");
        System.out.println("user-info2----->>>   " + user);
        return user;
    }

    /*@Async("MyAsyncThread")
    @GetMapping(value = "/testAsync")
    public CompletableFuture<String> testAsync() {
        System.out.println("----------------------------------------------");
        System.out.println(Thread.currentThread().getName() + " 正在处理请求");
        System.out.println("----------------------------------------------");
        String result = "success";
        return CompletableFuture.completedFuture(result);
    }*/

    @Autowired
    private AsyncService asyncService;
    @GetMapping("/testAsync1")
    public String test(){
        asyncService.testAsync();
        asyncService.testOne();
        return "SUCCESS";
    }

    @Autowired
    private TestAsyncService testAsyncService;
    @GetMapping("/testAsync2")
    public String test1() throws ExecutionException, InterruptedException {
        Future<String> userInfo = testAsyncService.getUserInfo(1L);
        String s = userInfo.get();
        if (StringUtils.isNotBlank(s)){
            testAsyncService.getAll();
        }
        return "SUCCESS";
    }

}
